﻿using System;
using System.Runtime.InteropServices;
using System.Security;

namespace steamswap
{
	#region Structures

	/// <summary>
	/// Defines a structure containing margin dimensions.
	/// </summary>
	[StructLayout(LayoutKind.Sequential)]
	public struct MARGINS
	{
		public int cxLeftWidth, 
			cxRightWidth, 
			cyTopHeight, 
			cyBottomHeight;
	}

	#endregion

	public class DwmApiInterop
	{
		#region Constants

		public const int HTCLIENT = 0x1;
		public const int HTCAPTION = 0x2;

		public const int WM_NCHITTEST = 0x84;
		public const int WM_DWMCOMPOSITIONCHANGED = 0x31E;

		#endregion

		#region Helper methods

		/// <summary>
		/// Determines whether the cursor is on the client area.
		/// </summary>
		/// <param name="hWnd">The window handle that is receiving and processing the window message.</param>
		/// <param name="uMsg">The window message.</param>
		/// <param name="wParam">Additional message information.</param>
		/// <param name="lParam">Additional message information.</param>
		/// <returns>true if the cursor is on the client area; otherwise, false.</returns>
		public static bool IsOnClientArea(IntPtr hWnd, int uMsg, IntPtr wParam, IntPtr lParam)
		{
			if (uMsg == WM_NCHITTEST)
			{
				if (DefaultWindowProcedure(hWnd, uMsg, wParam, lParam).ToInt32() == HTCLIENT)
				{
					return true;
				}
			}

			return false;
		}

		#endregion

		#region Managed wrapper methods

		/// <summary>
		/// Determines whether desktop composition is enabled on the client system.
		/// </summary>
		/// <returns>true if desktop composition is enabled; otherwise, false.</returns>
		public static bool IsCompositionEnabled()
		{
			bool isEnabled = false;
			NativeMethods.DwmIsCompositionEnabled(ref isEnabled);
			return isEnabled;
		}

		/// <summary>
		/// Extends the glass frame into the client area.
		/// </summary>
		/// <param name="hWnd">The window handle whose client area to extend glass into.</param>
		/// <param name="margins">The amount of glass to extend around the client area.</param>
		/// <returns>S_OK on success; otherwise, an HRESULT error code.</returns>
		public static int ExtendFrameIntoClientArea(IntPtr hWnd, ref MARGINS margins)
		{
			return NativeMethods.DwmExtendFrameIntoClientArea(hWnd, ref margins);
		}

		/// <summary>
		/// Invokes the default window message procedure for the given window handle.
		/// </summary>
		/// <param name="hWnd">The window handle that is receiving and processing the window message.</param>
		/// <param name="uMsg">The window message.</param>
		/// <param name="wParam">Additional message information.</param>
		/// <param name="lParam">Additional message information.</param>
		/// <returns>The result of the message processing, which depends on the message.</returns>
		public static IntPtr DefaultWindowProcedure(IntPtr hWnd, int uMsg, IntPtr wParam, IntPtr lParam)
		{
			return NativeMethods.DefWindowProc(hWnd, uMsg, wParam, lParam);
		}

		#endregion
	}

	[SuppressUnmanagedCodeSecurity]
	internal static class NativeMethods
	{
		[DllImport("dwmapi.dll")]
		internal static extern void DwmIsCompositionEnabled(ref bool isEnabled);

		[DllImport("dwmapi.dll")]
		internal static extern int DwmExtendFrameIntoClientArea(IntPtr hWnd, ref MARGINS margins);

		[DllImport("user32.dll")]
		internal static extern IntPtr DefWindowProc(IntPtr hWnd, int uMsg, IntPtr wParam, IntPtr lParam);
	}
}